﻿

#region File Description

#endregion


#region Using Statements

// System References
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;

// XNA References
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

// Freeform References
using Freeform.Framework;
using Freeform.Framework.Graphics;
using Freeform.Framework.Utility;
using Freeform.Framework.Input;
using Freeform.Framework.Menu;

// Internal References

#endregion


namespace CardGame.Adventure.Editor
{
    public class AdventureEditorWorld : World
    {

        #region Members

        public Entity Title { get; set; }
        public MenuItem_Text DialogTitle;
        public Dictionary<string, MenuItem_Text> FunctionTexts = new Dictionary<string, MenuItem_Text>();
        public Dictionary<string, Boolean> FunctionSwitches = new Dictionary<string, bool>();
        List<string> ReferenceKeys = new List<string>();
        public List<MenuItem_Text> EditorLabels = new List<MenuItem_Text>();
        public List<MenuItem_Text> InputTexts = new List<MenuItem_Text>();
        public List<MenuItem_Text> GuiTexts = new List<MenuItem_Text>();
        public List<MenuItem_Image2D> TextureSelectors = new List<MenuItem_Image2D>();
        public EditorTileClass EditorTileClass;
        public Viewport2D View;

        private Entity GuiBackground;
        private MenuItem_Image2D[] TexturePalette;
        private int[] TextureIndex;
        private List<Entity> GuiPane = new List<Entity>();
        private Dictionary<Entity, Vector2> GuiDefaults = new Dictionary<Entity, Vector2>();
        private String CapText = "";
        private String TemporaryText = "";
        private Int32 Increment = 0;

        private Boolean KeyboardForEditor = false;
        private Boolean CheckUserInput = false;
        private Boolean RequireNumbersOnly = false;
        private Boolean EnterPressed = false;
        private Boolean MenuItemClicked = false;
        private Boolean MenuItemRightClicked = false;
        private Boolean BackSpacePressed = false;
        private Boolean MouseLeftPressed = false;
        private Boolean MouseRightPressed = false;
        private int DrawingTexHeightOrNothing = -1;
        private Boolean DrawingRamp = false;

        // CameraAmount generates a number which is
        // exactly the number required to move the camera one tile width or height per key press.
        // The number of tile widths & heights the camera has moved is stored in the editor's AxisDifference
        // Point. That is then used to offset the position of the mouse by the amount of tile widths the camera has
        // moved and will return the correct tile index.
        private Vector2 CameraAmount = Vector2.Zero;
        private KeyBinding Up;
        private KeyBinding Down;
        private KeyBinding Left;
        private KeyBinding Right;
        private KeyBinding Save;
        private KeyBinding Load;
        private KeyBinding Enter;
        private KeyBinding BackSpace;


        #endregion


        #region Initialisation

        public AdventureEditorWorld()
        {
            // Make background invisible.
            BackgroundColour = new Color(Vector4.Zero);

            Up = new KeyBinding("Up", Keys.Up);
            Down = new KeyBinding("Down", Keys.Down);
            Left = new KeyBinding("Left", Keys.Left);
            Right = new KeyBinding("Right", Keys.Right);
            Save = new KeyBinding("Save", Keys.S);
            Load = new KeyBinding("Load", Keys.L);
            Enter = new KeyBinding("Enter", Keys.Enter);
            BackSpace = new KeyBinding("BackSpace", Keys.Back);

            // Create title.
            Title = new Entity(this);
            Title.SpatialProperties.Position = new Vector2(90, 15);
            Title.SpatialProperties.Size = new Vector2(15, 5);
            Title.Actor = new Actor_Text2D(Title, "Editor World", Game.Content.Load<SpriteFont>("Font/Basic"));
            (Title.Actor as Actor_Text2D).UseNaturalFontSize = true;
            (Title.Actor as Actor_Text2D).NaturalFontScaling = Vector2.One / 8f;
            Title.Actor.Depth = 0.71f;
            Title.Actor.ColourOverlay = Color.DeepSkyBlue;

            // Create buttons.
            FunctionTexts.Add("New", MakeNewItem(this, "New World", new Vector2(90, 20), Color.White, true, 0.71f));
            FunctionTexts.Add("Load", MakeNewItem(this, "Load World", new Vector2(90, 25), Color.White, true, 0.71f));
            FunctionTexts.Add("Save", MakeNewItem(this, "Save World", new Vector2(90, 30), Color.White, true, 0.71f));
            FunctionTexts.Add("Texture", MakeNewItem(this, "Texture", new Vector2(90, 35), Color.White, true, 0.71f));
            FunctionTexts.Add("Height", MakeNewItem(this, "H", new Vector2(90, 50), Color.White, false, 0.71f));
            FunctionTexts.Add("Tex", MakeNewItem(this, "T", new Vector2(92, 50), Color.White, false, 0.71f));
            FunctionTexts.Add("Ramp", MakeNewItem(this, "R", new Vector2(90, 55), Color.White, false, 0.71f));
            FunctionTexts.Add("Exit", MakeNewItem(this, "Exit", new Vector2(90, 40), Color.White, true, 0.71f));
            ReferenceKeys.Add("New");
            ReferenceKeys.Add("Load");
            ReferenceKeys.Add("Save");
            ReferenceKeys.Add("Texture");
            ReferenceKeys.Add("Height");
            ReferenceKeys.Add("Tex");
            ReferenceKeys.Add("Ramp");
            ReferenceKeys.Add("Exit");

            FunctionSwitches.Add("New", false);
            FunctionSwitches.Add("Load", false);
            FunctionSwitches.Add("Save", false);
            FunctionSwitches.Add("Texture", false);
            FunctionSwitches.Add("Height", false);
            FunctionSwitches.Add("Tex", false);
            FunctionSwitches.Add("Ramp", false);
            FunctionSwitches.Add("Exit", false);

            // Setup viewport.
            View = new Viewport2D(this);
            View.SpriteSorting = SpriteSortMode.FrontToBack;
            View.Camera.SpatialProperties.Size = new Vector2(100, 75);
            View.Depth = 0.5f;

            // Create gui.
            GuiBackground = MakeNewGuiSquare("background", new Vector2(90, 37.5f), Color.DarkGreen);

            TexturePalette = new MenuItem_Image2D[2];
            TextureIndex = new int[2];

            GuiPane.Add(GuiBackground);
            GuiPane.Add(Title);
            GuiDefaults.Add(GuiBackground, GuiBackground.SpatialProperties.Position);
            GuiDefaults.Add(Title, Title.SpatialProperties.Position);

            foreach (KeyValuePair<string, MenuItem_Text> a in FunctionTexts)
            {
                GuiPane.Add(a.Value);
                GuiDefaults.Add(a.Value, a.Value.SpatialProperties.Position);
            }

            #region Menu Item Events
            // Setup button clicked events.

            FunctionTexts["New"].ItemClicked += delegate(Object Item, EventArgs Args)
            {
                Boolean DoSetup = true;
                foreach (KeyValuePair<string, Boolean> a in FunctionSwitches)
                    if (a.Value == true)
                        DoSetup = false;

                if (DoSetup)
                {
                    foreach (KeyValuePair<string, MenuItem_Text> a in FunctionTexts)
                        if (a.Value.IsEnabled == true || a.Value.Actor.IsVisible == true)
                        { a.Value.IsEnabled = false; a.Value.Actor.IsVisible = false; }
                    SetUpGenericDialog("New", 7, 7, true, new Vector2(40,20), new Vector2(30,25), new Vector2(50,25),
                        false, false, new string[7] { "|||", "", "", "64", "64", "tempArtthree", ""}, 
                        new string[7] {"Name: ", "Width: ", "Height: ", "TileWidth: ", "TileHeight: ", "Art Source: ", "OK"}, "New World", false, "", "");
                }
            };
            FunctionTexts["Load"].ItemClicked += delegate(Object Item, EventArgs Args)
            {
                Boolean DoSetup = true;
                foreach (KeyValuePair<string, Boolean> a in FunctionSwitches)
                    if (a.Value == true)
                        DoSetup = false;

                if (DoSetup)
                {
                    foreach (KeyValuePair<string, MenuItem_Text> a in FunctionTexts)
                        if (a.Value.IsEnabled == true || a.Value.Actor.IsVisible == true)
                        { a.Value.IsEnabled = false; a.Value.Actor.IsVisible = false; }
                    SetUpGenericDialog("Load", 0, 0, false, new Vector2(40, 20), new Vector2(40, 30), new Vector2(50, 25),
                        false, false, null,
                        null, "Load World", true, "*.xml", "");
                }
            };
            FunctionTexts["Save"].ItemClicked += delegate(Object Item, EventArgs Args)
            {
                Boolean DoSetup = true;
                foreach (KeyValuePair<string, Boolean> a in FunctionSwitches)
                    if (a.Value == true)
                        DoSetup = false;
                if (EditorTileClass == null)
                    DoSetup = false;

                if (DoSetup)
                {
                    foreach (KeyValuePair<string, MenuItem_Text> a in FunctionTexts)
                        if (a.Value.IsEnabled == true || a.Value.Actor.IsVisible == true)
                        { a.Value.IsEnabled = false; a.Value.Actor.IsVisible = false; }
                    SetUpGenericDialog("Save", 0, 1, true, new Vector2(40, 20), new Vector2(40, 30), new Vector2(50, 25),
                        false, false, new string[1] {" "},
                        null, "Save World", true, "*.xml", "FileName: ");

                    CheckUserInput = false;
                }
            };
            FunctionTexts["Texture"].ItemClicked += delegate(Object Item, EventArgs Args)
            {
                Boolean DoSetup = true;
                foreach (KeyValuePair<string, Boolean> a in FunctionSwitches)
                    if (a.Value == true)
                        DoSetup = false;

                if (DoSetup && EditorTileClass != null)
                {
                    foreach (KeyValuePair<string, MenuItem_Text> a in FunctionTexts)
                        if (a.Value.IsEnabled == true || a.Value.Actor.IsVisible == true)
                        { a.Value.IsEnabled = false; a.Value.Actor.IsVisible = false; }
                    SetUpTexturesDialog();
                }
            };
            FunctionTexts["Height"].ItemClicked += delegate(Object Item, EventArgs Args)
            {
                DrawingTexHeightOrNothing = 2;
                FunctionTexts["Height"].Actor.ColourOverlay = Color.Red;
                FunctionTexts["Tex"].Actor.ColourOverlay = Color.White;
                FunctionTexts["Ramp"].Actor.ColourOverlay = Color.White;
            };
            FunctionTexts["Tex"].ItemClicked += delegate(Object Item, EventArgs Args)
            {
                DrawingTexHeightOrNothing = 1;
                FunctionTexts["Tex"].Actor.ColourOverlay = Color.Red;
                FunctionTexts["Height"].Actor.ColourOverlay = Color.White;
                FunctionTexts["Ramp"].Actor.ColourOverlay = Color.White;
            };
            FunctionTexts["Ramp"].ItemClicked += delegate(Object Item, EventArgs Args)
            {
                DrawingTexHeightOrNothing = -1;
                DrawingRamp = true;
                FunctionTexts["Tex"].Actor.ColourOverlay = Color.White;
                FunctionTexts["Height"].Actor.ColourOverlay = Color.White;
                FunctionTexts["Ramp"].Actor.ColourOverlay = Color.Red;
            };

            #endregion

            #region Input Bindings
            Up.Pressed += delegate(Object Item, EventArgs Args)
            {
                if (!KeyboardForEditor && Increment > 0)
                            Increment--;

                else if (KeyboardForEditor && EditorTileClass != null)
                {
                    View.Camera.SpatialProperties.Position -= new Vector2(0f, CameraAmount.Y);
                    foreach (Entity e in GuiPane)
                        e.SpatialProperties.Position -= new Vector2(0f, CameraAmount.Y);
                    EditorTileClass.AxisDifference = new Point(EditorTileClass.AxisDifference.X, EditorTileClass.AxisDifference.Y - 1);
                }
            };
            Down.Pressed += delegate(Object Item, EventArgs Args)
            {
                if (!KeyboardForEditor && Increment < EditorLabels.Count - 1)
                            Increment++;

                else if(KeyboardForEditor && EditorTileClass != null)
                {
                    View.Camera.SpatialProperties.Position += new Vector2(0f, CameraAmount.Y);
                    foreach (Entity e in GuiPane)
                        e.SpatialProperties.Position += new Vector2(0f, CameraAmount.Y);
                    EditorTileClass.AxisDifference = new Point(EditorTileClass.AxisDifference.X, EditorTileClass.AxisDifference.Y + 1);
                }
            };
            Left.Pressed += delegate(Object Item, EventArgs Args)
            {
                if (EditorTileClass != null && !EditorTileClass.IsDisposed)
                {
                    View.Camera.SpatialProperties.Position -= new Vector2(CameraAmount.X, 0f);
                    foreach (Entity e in GuiPane)
                        e.SpatialProperties.Position -= new Vector2(CameraAmount.X, 0f);
                    EditorTileClass.AxisDifference = new Point(EditorTileClass.AxisDifference.X - 1, EditorTileClass.AxisDifference.Y);
                }
            };
            Right.Pressed += delegate(Object Item, EventArgs Args)
            {
                if (EditorTileClass != null && !EditorTileClass.IsDisposed)
                {
                    View.Camera.SpatialProperties.Position += new Vector2(CameraAmount.X, 0f);
                    foreach (Entity e in GuiPane)
                        e.SpatialProperties.Position += new Vector2(CameraAmount.X, 0f);
                    EditorTileClass.AxisDifference = new Point(EditorTileClass.AxisDifference.X + 1, EditorTileClass.AxisDifference.Y);
                }
            };
            Enter.Pressed += delegate(Object Item, EventArgs Args) { EnterPressed = true; };
            BackSpace.Pressed += delegate(Object Item, EventArgs Args) { BackSpacePressed = true; };
            FunctionTexts["Exit"].ItemClicked += delegate(Object Item, EventArgs Args) { Game.Exit(); };

            #endregion
        }

        #endregion


        #region Update

        protected override void DoUpdate(GameTime Time)
        {
            base.DoUpdate(Time);

            if (Game.Input.MouseState_Current.LeftButton == ButtonState.Pressed &&
                Game.Input.MouseState_Previous.LeftButton == ButtonState.Released)
            {
                MouseLeftPressed = true;
                MouseRightPressed = false;
            }
            if (Game.Input.MouseState_Current.RightButton == ButtonState.Pressed &&
                Game.Input.MouseState_Previous.RightButton == ButtonState.Released)
            {
                MouseRightPressed = true;
                MouseLeftPressed = false;
            }

            if (FunctionSwitches["New"] == true)
            {
                KeyboardForEditor = false;
                CapText = Game.Input.GetCapturedText();
                if (CapText == "^$#")
                {
                    if (TemporaryText.Length > 0) TemporaryText = TemporaryText.Substring(0, TemporaryText.Length - 1);
                    Game.Input.ResetText();
                    CapText = "";
                }
                InputTexts[Increment].TextActor.Text = TemporaryText + CapText;
                if (InputTexts[Increment].TextActor.Text == "")
                    InputTexts[Increment].TextActor.Text = "|||";

                if (EnterPressed)
                {
                    Game.Input.CaptureText = false;

                    if (EditorLabels[Increment].TextActor.Text == "Width: "
                        || EditorLabels[Increment].TextActor.Text == "Height: "
                        || EditorLabels[Increment].TextActor.Text == "TileHeight: "
                        || EditorLabels[Increment].TextActor.Text == "TileWidth: ")
                        RequireNumbersOnly = true;
                    else
                        RequireNumbersOnly = false;

                    if (Increment == EditorLabels.Count -1)
                    {
                        Increment = 0;
                        Game.Input.ResetText();
                        CapText = "";

                        FunctionSwitches["New"] = false;
                        foreach (MenuItem_Text m in InputTexts)
                        {
                            if (m.TextActor.Text == "")
                                m.TextActor.Text = "Default5";
                        }
                        DisposeTexts();
                        foreach (KeyValuePair<string, MenuItem_Text> a in FunctionTexts)
                            ReInstateMenuItem(a.Key);
                        EditorTileClass = new EditorTileClass(this, int.Parse(RecoverNumbers(InputTexts[1].TextActor.Text)),
                            int.Parse(RecoverNumbers(InputTexts[2].TextActor.Text)));
                        EditorTileClass.SpatialProperties.Position = new Vector2(0f, 0);
                        EditorTileClass.SpatialProperties.Size = new Vector2(1, 1);
                        EditorTileClass.TileWidth = int.Parse(RecoverNumbers(InputTexts[3].TextActor.Text));
                        EditorTileClass.TileHeight = int.Parse(RecoverNumbers(InputTexts[4].TextActor.Text));
                        EditorTileClass.ArtFileName = InputTexts[5].TextActor.Text;
                        EditorTileClass.SetUpArtAssets();
                        TemporaryText = InputTexts[0].TextActor.Text;
                        MouseLeftPressed = false;
                        MouseRightPressed = false;

                        SetUpGui();

                        CameraAmount = new Vector2(EditorTileClass.DrawTileWidth / (View.RenderTarget.Width / View.Camera.SpatialProperties.Size.X),
                           EditorTileClass.DrawTileHeight / (View.RenderTarget.Height / View.Camera.SpatialProperties.Size.Y));
                    }
                    else
                    {
                        if (RequireNumbersOnly)
                            CapText = RecoverNumbers(CapText);
                        EditorLabels[Increment].TextActor.ColourOverlay = Color.DeepSkyBlue;
                        InputTexts[Increment].TextActor.ColourOverlay = Color.DeepSkyBlue;
                        if (InputTexts[Increment + 1].TextActor.Text == "" || InputTexts[Increment + 1].TextActor.Text == " ")
                            InputTexts[Increment + 1].TextActor.Text = "|||";
                        else
                        {
                            TemporaryText = InputTexts[Increment + 1].TextActor.Text;
                        }
                        Increment++;
                        Game.Input.ResetText();
                        Game.Input.CaptureText = true;
                        if (Increment == EditorLabels.Count - 1)
                        {
                            InputTexts[InputTexts.Count - 1].TextActor.ColourOverlay = Color.Green;
                            TemporaryText = "|||";
                            EditorLabels[EditorLabels.Count - 1].TextActor.ColourOverlay = Color.Green;
                            Game.Input.CaptureText = false;
                        }
                    }
                    EnterPressed = false;
                }
            }
            else if (FunctionSwitches["Load"] == true)
            {
                KeyboardForEditor = false;
                foreach (MenuItem_Text a in EditorLabels)
                    if (a.IsHighlighted)
                        for (int i = 0; i < EditorLabels.Count; i++)
                            if (a.TextActor.Text == EditorLabels[i].TextActor.Text)
                                Increment = i;

                if (EnterPressed || MenuItemClicked)
                {
                    DisposeTexts();
                    foreach (KeyValuePair<string, MenuItem_Text> a in FunctionTexts)
                        ReInstateMenuItem(a.Key);
                    FunctionSwitches["Load"] = false;

                    EditorTileClass = new EditorTileClass(this, 52, 52);
                    EditorTileClass.SpatialProperties.Position = new Vector2(0f, 0);
                    EditorTileClass.SpatialProperties.Size = new Vector2(1, 1);
                    EditorTileClass.FileName = EditorLabels[Increment].TextActor.Text;
                    EditorTileClass.IntiateLoadProcedure = true;
                    MouseLeftPressed = false;
                    MouseRightPressed = false;

                    CameraAmount = new Vector2(EditorTileClass.DrawTileWidth / (View.RenderTarget.Width / View.Camera.SpatialProperties.Size.X),
                           EditorTileClass.DrawTileHeight / (View.RenderTarget.Height / View.Camera.SpatialProperties.Size.Y));

                    SetUpGui();
                    EnterPressed = false;
                    MenuItemClicked = false;
                }
            }
            else if (FunctionSwitches["Save"] == true)
            {
                KeyboardForEditor = false;
                Game.Input.CaptureText = true;
                CapText = Game.Input.GetCapturedText();
                if (CapText == "^$#")
                {
                    if (TemporaryText.Length > 0) TemporaryText = TemporaryText.Substring(0, TemporaryText.Length - 1);
                    Game.Input.ResetText();
                    CapText = "";
                }
                InputTexts[0].TextActor.Text = TemporaryText + CapText;
                if (InputTexts[0].TextActor.Text == "")
                    InputTexts[0].TextActor.Text = "|||";

                if (!CheckUserInput)
                {
                    foreach (MenuItem_Text a in EditorLabels)
                        if (a.TextActor.Text != "FileName: " && a.IsHighlighted)
                            for (int i = 0; i < EditorLabels.Count; i++)
                                if (a.TextActor.Text == EditorLabels[i].TextActor.Text)
                                    Increment = i;
                }
                if (MenuItemClicked)
                {
                    TemporaryText = EditorLabels[Increment].TextActor.Text;
                    MenuItemClicked = false;
                }

                if (EnterPressed && !CheckUserInput)
                {
                    Game.Input.CaptureText = false;
                    foreach (MenuItem_Text m in EditorLabels)
                    {
                        if(m.TextActor.Text == InputTexts[0].TextActor.Text)
                            CheckUserInput = true;
                        m.TextActor.ColourOverlay = Color.DeepSkyBlue;
                        m.ItemHighlighted -= ItemHighlightedGreen;
                        m.ItemLeft -= ItemLeft;
                        InputTexts[0].TextActor.ColourOverlay = Color.DeepSkyBlue;
                    }
                    foreach (MenuItem_Text m in InputTexts)
                    {
                        if (m.TextActor.Text == "" || m.TextActor.Text == "|||")
                        {
                            CheckUserInput = true;
                            TemporaryText = "Default5";
                        }
                        m.TextActor.ColourOverlay = Color.DeepSkyBlue;
                    }
                    if (!CheckUserInput)
                    {
                        DisposeTexts();
                        foreach (KeyValuePair<string, MenuItem_Text> a in FunctionTexts)
                            ReInstateMenuItem(a.Key);
                        EditorTileClass.FileName = InputTexts[0].TextActor.Text;
                        EditorTileClass.IntiateSaveProcedure = true;
                        FunctionSwitches["Save"] = false;
                        KeyboardForEditor = true; ;
                        EditorTileClass.IsVisible = true;
                        MouseLeftPressed = false;
                        MouseRightPressed = false;
                    }
                    else
                    {
                        EditorLabels.Add(MakeNewItem(this, "Are you sure you want to overwrite?", new Vector2(40,5), Color.Gold, false, 0.72f));
                        EditorLabels.Add(MakeNewItem(this, "Press Enter to overwrite or Backspace to go back",
                            new Vector2(40,10), Color.Green, false, 0.72f));
                    }
                    EnterPressed = false;
                }
                if (CheckUserInput)
                {
                    if (EnterPressed)
                    {
                        EditorTileClass.FileName = InputTexts[0].TextActor.Text;
                        DisposeTexts();
                        foreach (KeyValuePair<string, MenuItem_Text> a in FunctionTexts)
                            ReInstateMenuItem(a.Key);
                        EditorTileClass.IntiateSaveProcedure = true;
                        Game.Input.CaptureText = false;
                        EnterPressed = false;
                        FunctionSwitches["Save"] = false;
                        KeyboardForEditor = true;
                        EditorTileClass.IsVisible = true;
                        MouseLeftPressed = false;
                        MouseRightPressed = false;
                    }
                    else if (BackSpacePressed)
                    {
                        InputTexts[0].TextActor.ColourOverlay = Color.Gold;
                        foreach (MenuItem_Text m in EditorLabels)
                        {
                            m.TextActor.ColourOverlay = Color.White;
                            m.ItemHighlighted += ItemHighlightedGreen;
                            m.ItemLeft += ItemLeft;
                            if (m.TextActor.Text == "Are you sure you want to overwrite?" ||
                                m.TextActor.Text == "Press Enter to overwrite or Backspace to go back")
                                m.Dispose();
                            if (m.TextActor.Text == "FileName: ")
                                m.TextActor.ColourOverlay = Color.Gold;
                        }
                        CheckUserInput = false;
                        BackSpacePressed = false;
                        Game.Input.CaptureText = true;
                    }
                }
                BackSpacePressed = false;
            }
            else if (FunctionSwitches["Texture"])
            {
                if (MenuItemClicked)
                {
                    for(int i = 0; i < TextureSelectors.Count; i++)
                        if (TextureSelectors[i].IsHighlighted)
                        {
                            TexturePalette[0].ImageActor.Animations.Current.FreezeOnFrame(i);
                            TextureIndex[0] = i;

                            MenuItemClicked = false;
                            FunctionSwitches["Texture"] = false;
                            KeyboardForEditor = true;
                            EditorTileClass.IsVisible = true;
                            foreach (MenuItem_Image2D a in TextureSelectors)
                                a.Dispose();
                            TextureSelectors.Clear();
                            MouseLeftPressed = false;
                            MouseRightPressed = false;
                            SetUpGui();
                        }
                }
                if (MenuItemRightClicked)
                {
                    for (int i = 0; i < TextureSelectors.Count; i++)
                        if (TextureSelectors[i].IsHighlighted)
                        {
                            TexturePalette[1].ImageActor.Animations.Current.FreezeOnFrame(i);
                            TextureIndex[1] = i;

                            MenuItemRightClicked = false;
                            FunctionSwitches["Texture"] = false;
                            KeyboardForEditor = true;
                            EditorTileClass.IsVisible = true;
                            foreach (MenuItem_Image2D a in TextureSelectors)
                                a.Dispose();
                            TextureSelectors.Clear();
                            MouseLeftPressed = false;
                            MouseRightPressed = false;
                            SetUpGui();
                        }
                }
            }
            if (EditorTileClass != null && EditorTileClass.IsVisible && GuiBackground.IsMouseOver() == false && KeyboardForEditor)
            {
                if (MouseLeftPressed)
                {
                    if(DrawingTexHeightOrNothing == 2)
                        EditorTileClass.ModifyCell('Y', 1);

                    else if (DrawingTexHeightOrNothing == 1)
                        EditorTileClass.SetCell('X', TextureIndex[0]);

                    else if (DrawingTexHeightOrNothing == -1 && DrawingRamp == true)
                        EditorTileClass.ModifyCell('Y', 0.5f);
                    MouseLeftPressed = false;
                }
                if (MouseRightPressed)
                {
                    if (DrawingTexHeightOrNothing == 2)
                        EditorTileClass.ModifyCell('Y', -1);

                    else if (DrawingTexHeightOrNothing == 1)
                        EditorTileClass.SetCell('X', TextureIndex[1]);

                    else if (DrawingTexHeightOrNothing == -1 && DrawingRamp == true)
                        EditorTileClass.ModifyCell('Y', -0.5f);
                    MouseRightPressed = false;
                }
            }
            else { MouseLeftPressed = false; MouseRightPressed = false; }
        }

        #endregion


        #region Utility

        #region Text Constructors & Methods
        private void ItemHighlighted(Object Item, EventArgs Args)
        {
            MenuItem_Text Text = Item as MenuItem_Text;
            Text.Actor.ColourOverlay = Color.Red;
            Text.TextActor.NaturalFontScaling = Vector2.One / 7f;
        }
        private void ItemHighlightedGreen(Object Item, EventArgs Args)
        {
            MenuItem_Text Text = Item as MenuItem_Text;
            Text.Actor.ColourOverlay = Color.Green;
            Text.TextActor.NaturalFontScaling = Vector2.One / 7f;
        }
        private void ItemLeft(Object Item, EventArgs Args)
        {
            MenuItem_Text Text = Item as MenuItem_Text;
            Text.Actor.ColourOverlay = Color.White;
            Text.TextActor.NaturalFontScaling = Vector2.One / 9f;
        }
        private MenuItem_Text MakeNewItem(World W, String Text, Vector2 Position, Color Color, Boolean Highlightable, float Depth)
        {
            MenuItem_Text Item = new MenuItem_Text(W, Text, "Font/Basic");
            Item.SpatialProperties.Position = Position;
            Item.TextActor.NaturalFontScaling = Vector2.One / 9f;
            Item.TextActor.ColourOverlay = Color;
            if (Highlightable)
            {
                Item.ItemHighlighted += ItemHighlighted;
                Item.ItemLeft += ItemLeft;
            }
            Item.Actor.Depth = Depth;
            return Item;
        }
        private void MakeTextLists(ref List<MenuItem_Text> List, Vector2 BeginPosi, Boolean Highlightable)
        {
            int incrementer = 0;
            foreach (MenuItem_Text Item in List)
            {
                Item.SpatialProperties.Position = new Vector2(BeginPosi.X, BeginPosi.Y + (incrementer * 5));
                Item.TextActor.NaturalFontScaling = Vector2.One / 9f;
                Item.TextActor.ColourOverlay = Color.Gold;
                if (Highlightable)
                {
                    Item.ItemHighlighted += ItemHighlighted;
                    Item.ItemLeft += ItemLeft;
                }
                Item.Actor.Depth = 0.7f;
                incrementer++;
            }
        }
        private void MakeTextLists(ref List<MenuItem_Text> List, Vector2 BeginPosi, string[] strings, bool Highlightable)
        {
            int incrementer = 0;
            foreach (MenuItem_Text Item in List)
            {
                Item.SpatialProperties.Position = new Vector2(BeginPosi.X, BeginPosi.Y + (incrementer * 5));
                Item.TextActor.NaturalFontScaling = Vector2.One / 9f;
                Item.TextActor.ColourOverlay = Color.White;
                if (Highlightable)
                {
                    Item.ItemHighlighted += ItemHighlightedGreen;
                    Item.ItemLeft += ItemLeft;
                }
                Item.Actor.Depth = 0.7f;
                if (incrementer >= strings.Length || incrementer < 0)
                    Item.TextActor.Text = " ";
                else
                    Item.TextActor.Text = strings[incrementer];
                incrementer++;
            }
        }
        private void MakeTextLists(ref List<MenuItem_Text> List, Vector2 BeginPosi, string[] strings, bool Highlightable, Color off, Color On)
        {
            int incrementer = 0;
            foreach (MenuItem_Text Item in List)
            {
                Item.SpatialProperties.Position = new Vector2(BeginPosi.X, BeginPosi.Y + (incrementer * 5));
                Item.TextActor.NaturalFontScaling = Vector2.One / 9f;
                Item.TextActor.ColourOverlay = off;
                if (Highlightable)
                {
                    if (On == Color.Green)
                        Item.ItemHighlighted += ItemHighlightedGreen;
                    else Item.ItemHighlighted += ItemHighlighted;
                    Item.ItemLeft += ItemLeft;
                }
                Item.Actor.Depth = 0.7f;
                if (incrementer >= strings.Length || incrementer < 0)
                    Item.TextActor.Text = " ";
                else
                    Item.TextActor.Text = strings[incrementer];
                incrementer++;
            }
        }
        private string RecoverNumbers(string inpString)
        {
            string carryString = "";
            for (int i = 0; i < inpString.Length; i++)
            {
                char a = inpString[i];
                if (a == '0' || a == '1' || a == '2' || a == '3'
                     || a == '4' || a == '5' || a == '6' || a == '7'
                     || a == '8' || a == '9')
                    carryString += a;
            }
            return carryString;
        }
        private string StripNumbers(string inpString)
        {
            string carryString = "";
            for (int i = 0; i < inpString.Length; i++)
            {
                char a = inpString[i];
                if (a != '0' && a != '1' && a != '2' && a != '3'
                     && a != '4' && a != '5' && a != '6' && a != '7'
                     && a != '8' && a != '9')
                    carryString += a;
            }
            return carryString;
        }
        private void ReInstateMenuItem(string key)
        {
            FunctionTexts[key].Actor.IsVisible = true;
            FunctionTexts[key].IsEnabled = true;
        }
        private void ReInstateMenuItem(string key, Vector2 posi)
        {
            FunctionTexts[key].SpatialProperties.Position = posi;
            FunctionTexts[key].Actor.IsVisible = true;
            FunctionTexts[key].IsEnabled = true;
        }
        private void DemoteMenuItem(string key)
        {
            FunctionTexts[key].Actor.IsVisible = false;
            FunctionTexts[key].IsEnabled = false;
        }
        private void DemoteMenuItem(string key, Vector2 posi)
        {
            FunctionTexts[key].SpatialProperties.Position = posi;
            FunctionTexts[key].Actor.IsVisible = false;
            FunctionTexts[key].IsEnabled = false;
        }
        private void DisposeTexts()
        {
            foreach (MenuItem_Text m in InputTexts)
                m.Dispose();
            foreach (MenuItem_Text m in EditorLabels)
                m.Dispose();
            foreach (MenuItem_Text m in GuiTexts)
                m.Dispose();
            DialogTitle.Dispose();
            GuiTexts.Clear();
        }
        #endregion

        #region Image Constructors
        private void ImageItemHighlighted(Object Item, EventArgs Args)
        {
            MenuItem_Image2D Image = Item as MenuItem_Image2D;
            Image.Actor.ColourOverlay = Color.Red;
        }
        private void ImageItemLeft(Object Item, EventArgs Args)
        {
            MenuItem_Image2D Image = Item as MenuItem_Image2D;
            Image.Actor.ColourOverlay = Color.White;
        }
        private MenuItem_Image2D MakeNewImageItem(World W, String TextureName, Vector2 Position, int PausedFrame, Color Color, Boolean Highlightable, float Depth)
        {
            MenuItem_Image2D Item = new MenuItem_Image2D(W, "Texture/Adventure/Art/" + TextureName, EditorTileClass.TileWidth, PausedFrame);
            Item.SpatialProperties.Position = Position;
            Item.ImageActor.ColourOverlay = Color;
            if (Highlightable)
            {
                Item.ItemHighlighted += ImageItemHighlighted;
                Item.ItemLeft += ImageItemLeft;
            }
            Item.Actor.Depth = Depth;
            return Item;
        }
        #endregion

        #region Setup Methods

        private void SetUpGenericDialog(string Key, int MaxLabels, int MaxInputs,
            Boolean CaptureText, Vector2 posi1, Vector2 Posi2, Vector2 Posi3,
            Boolean InputHighlight, Boolean EditorHighlight, string[] inputStrings, string[] editorStrings, 
            string titleText, Boolean ListFiles, string ext, string optionalTitle)
        {
            if (EditorTileClass != null)
                if (EditorTileClass.IsVisible)
                    EditorTileClass.IsVisible = false;
            if (EditorLabels.Count > 0)
                EditorLabels.Clear();
            if (InputTexts.Count > 0)
                InputTexts.Clear();

            foreach (string a in ReferenceKeys)
            {
                if (a != Key)
                {
                    FunctionSwitches[a] = false;
                    DemoteMenuItem(a);
                }
            }
            FunctionSwitches[Key] = true;

            if (MaxInputs > 0)
                for (int i = 0; i < MaxInputs; i++)
                    InputTexts.Add(new MenuItem_Text(this, "", "Font/Basic"));
            if (!ListFiles && MaxLabels > 0)
                for (int i = 0; i < MaxLabels; i++)
                    EditorLabels.Add(new MenuItem_Text(this, "", "Font/Basic"));

            if (inputStrings != null)
                MakeTextLists(ref InputTexts, Posi3, inputStrings, InputHighlight);
            if (editorStrings != null)
                MakeTextLists(ref EditorLabels, Posi2, editorStrings, EditorHighlight);
            DialogTitle = MakeNewItem(this, titleText, posi1, Color.DeepSkyBlue, false, 0.71f);

            if (ListFiles)
            {
                DirectoryInfo Dir = new DirectoryInfo(Game.Content.RootDirectory);
                string[] dirPaths;
                if (!Dir.Exists)
                    throw new DirectoryNotFoundException();

                FileInfo[] Files = Dir.GetFiles("*" + ext);
                dirPaths = new string[Files.Length];
                int count = 0;
                foreach (FileInfo F in Files)
                {
                    dirPaths[count] = Path.GetFileNameWithoutExtension(F.Name);
                    EditorLabels.Add(new MenuItem_Text(this, " ", "Font/Basic"));
                    count++;
                }

                MakeTextLists(ref EditorLabels, Posi2, dirPaths, true, Color.White, Color.Green);
                foreach (MenuItem_Text m in EditorLabels)
                    m.ItemClicked += delegate(Object Itema, EventArgs Argsa) { MenuItemClicked = true; };

                GuiTexts.Add(MakeNewItem(this, "A", new Vector2(Posi2.X - 15, 30), Color.White, true, 0.71f));
                GuiTexts[0].ItemClicked += ArrowUp;
                GuiTexts.Add(MakeNewItem(this, "V", new Vector2(Posi2.X - 15, 35), Color.White, true, 0.71f));
                GuiTexts[1].ItemClicked += ArrowDown;
                if (optionalTitle != "")
                    GuiTexts.Add(MakeNewItem(this, optionalTitle, new Vector2(Posi2.X, Posi2.Y - 5), Color.Gold, false, 0.71f));
            }

            if (CaptureText)
                Game.Input.CaptureText = true;
        }

        private void SetUpGui()
        {
            GuiDefaults.Clear();
            Title.SpatialProperties.Position = new Vector2(90, 5);
            ReInstateMenuItem("New", new Vector2(90, 10));
            ReInstateMenuItem("Load", new Vector2(90, 15));
            ReInstateMenuItem("Save", new Vector2(90, 20));
            ReInstateMenuItem("Texture", new Vector2(90, 25));
            ReInstateMenuItem("Height", new Vector2(90, 50));
            ReInstateMenuItem("Tex", new Vector2(92, 50));
            ReInstateMenuItem("Ramp", new Vector2(90, 55));
            ReInstateMenuItem("Exit", new Vector2(90, 70));
            if (TexturePalette[0] == null)
            {
                TexturePalette[0] = MakeNewImageItem(this, EditorTileClass.ArtFileName, new Vector2(85, 50), 0, Color.White, false, 0.72f);
                TexturePalette[0].SpatialProperties.Size = new Vector2(TexturePalette[0].SpatialProperties.Size.X / EditorTileClass.NumberOfTextures, TexturePalette[0].SpatialProperties.Size.Y);
                GuiPane.Add(TexturePalette[0]);
            }
            if (TexturePalette[1] == null)
            {
                TexturePalette[1] = MakeNewImageItem(this, EditorTileClass.ArtFileName, new Vector2(86, 51), 0, Color.White, false, 0.71f);
                TexturePalette[1].SpatialProperties.Size = new Vector2(TexturePalette[1].SpatialProperties.Size.X / EditorTileClass.NumberOfTextures, TexturePalette[1].SpatialProperties.Size.Y);
                GuiPane.Add(TexturePalette[1]);
            }
            foreach (Entity e in GuiPane)
                GuiDefaults.Add(e, e.SpatialProperties.Position);

            KeyboardForEditor = true;
        }

        private void ArrowUp(Object Item, EventArgs Args)
        {
            foreach (MenuItem_Text a in EditorLabels) a.SpatialProperties.Position += new Vector2(0, -5);
        }
        private void ArrowDown(Object Item, EventArgs Args)
        {
            foreach (MenuItem_Text a in EditorLabels) a.SpatialProperties.Position += new Vector2(0, 5);
        }

        private Entity MakeNewGuiSquare(string textureFileName, Vector2 posi, Color color)
        {
            Entity A = new Entity(this);
            A.Actor = new Actor_Image2D(A, "Texture/Adventure/Art/" + textureFileName);
            Actor_Image2D a = A.Actor as Actor_Image2D;
            int x = a.Animations.Current.Texture.Bounds.Width;
            int y = a.Animations.Current.Texture.Bounds.Height;
            A.Actor.Depth = 0.7f;
            A.Actor.ColourOverlay = color;
            A.SpatialProperties.Size = new Vector2(x / (View.RenderTarget.Width / View.Camera.SpatialProperties.Size.X),
                y / (View.RenderTarget.Height / View.Camera.SpatialProperties.Size.Y));
            A.SpatialProperties.Position = posi;
            return A;
        }

        private void SetUpTexturesDialog()
        {
            FunctionSwitches["Texture"] = true;
            View.Camera.SpatialProperties.Position = Vector2.Zero;
            foreach (Entity e in GuiPane)
                e.SpatialProperties.Position = GuiDefaults[e];
            EditorTileClass.AxisDifference = Point.Zero;

            if (EditorTileClass != null || EditorTileClass.IsVisible)
                EditorTileClass.IsVisible = false;
            Texture2D Tex = Game.Content.Load<Texture2D>("Texture/Adventure/Art/" + EditorTileClass.ArtFileName);
            int numberOfTextures = Tex.Bounds.Width / EditorTileClass.TileWidth;
            for (int i = 0; i < numberOfTextures; i++)
            {
                TextureSelectors.Add(MakeNewImageItem(this, EditorTileClass.ArtFileName, new Vector2(10 +(5 *i), 10), i, Color.White, true, .72f));
                TextureSelectors[TextureSelectors.Count - 1].SpatialProperties.Size = new Vector2(TextureSelectors[TextureSelectors.Count - 1].SpatialProperties.Size.X / numberOfTextures, TextureSelectors[TextureSelectors.Count - 1].SpatialProperties.Size.Y);
                TextureSelectors[TextureSelectors.Count - 1].SpatialProperties.Position = new Vector2(20 + (TextureSelectors[TextureSelectors.Count - 1].SpatialProperties.Size.X * i), 10);
                TextureSelectors[TextureSelectors.Count - 1].ItemClicked += delegate(Object Itema, EventArgs Argsa) { MenuItemClicked = true; };
                TextureSelectors[TextureSelectors.Count - 1].ItemRightClicked += delegate(Object Itema, EventArgs Argsa) { MenuItemRightClicked = true; };
            }
        }

        #endregion

        #endregion
    }
}
